﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;
using 实时曲线.Models;

namespace 实时曲线
{
    public partial class FrmTrend : Form
    {
        // 定时器用于刷新曲线数据
        System.Timers.Timer timer = new System.Timers.Timer();
        // 图标最多显示30个
        int showCount = 30;

        public FrmTrend()
        {
            InitializeComponent();
        }

        private void FrmTrend_Load(object sender, EventArgs e)
        {
            // 清空参数列表面板
            panelParaList.Controls.Clear();
            // 清空曲线图标序列
            chart1.Series.Clear();

            // 参数列表的加载
            LoadChkParaList();

            // 初始化定时器
            timer = new System.Timers.Timer();
            timer.Interval = 1000;
            timer.Elapsed += Timer_Elapsed;
            // 重复执行(默认为true)
            timer.AutoReset = true;
            timer.Start();
        }

        private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            // 子线程:不能直接操作控件
            if (this.IsHandleCreated)
            {
                this.Invoke(new Action(() =>
                {
                    // 获取所有参数名集合
                    List<string> strParaNames = CommonClass.trendParaInfos.Select(a => a.ParaName).ToList();

                    foreach (Series series in chart1.Series)
                    {
                        // 重新绑定数据
                        List<DateTime> xvalues = new List<DateTime>();
                        List<string> yvalues = new List<string>();
                        int index = strParaNames.IndexOf(series.Tag.ToString()); // 位置
                        int actTrendCount = CommonClass.trendCacheInfos.Count; // 缓存列表实际数目
                        // 开始位置
                        int start = 0;
                        // 结束位置
                        int end = 0;
                        start = actTrendCount <= showCount ? 0 : actTrendCount - showCount;
                        end = actTrendCount;
                        for (int i = start; i < end; i++)
                        {
                            List<TrendCacheInfo> list = CommonClass.trendCacheInfos[i]; // 第i条缓存
                            xvalues.Add(list[index].InsertTime);
                            yvalues.Add(list[index].ParaValue);
                        }
                        // 绑定x、y集合
                        series.Points.DataBindXY(xvalues, yvalues); // 序列绑定
                    }

                }));
            }
        }

        private void LoadChkParaList()
        {
            // 遍历参数名-参数描述键值对,每个参数--复选框
            Point firstPoint = new Point(29, 22);// y轴 +40

            int i = 0;
            foreach (string paraName in CommonClass.trendParaInfos.Select(a => a.ParaName).ToList())
            {
                string note = CommonClass.trendParaInfos.FirstOrDefault(a => a.ParaName == paraName).Note;
                // 每个复选框间隔40像素
                Point location = new Point(firstPoint.X, firstPoint.Y + i * 40);
                CheckBox cbk = CreateChkBox(paraName, note, location);
                panelParaList.Controls.Add(cbk);
                i++;
            }
        }

        private CheckBox CreateChkBox(string paraName, string note, Point location)
        {
            // 创建一个复选框
            CheckBox chk = new CheckBox();
            chk.Checked = false; // 不勾选
            chk.Tag = paraName; // 参数名
            chk.Text = note;// 参数描述文本
            chk.ForeColor = Color.Gray; // 文本颜色
            chk.Font = new Font("微软雅黑", 9F, FontStyle.Regular, GraphicsUnit.Point, ((byte)(134)));// 字体
            chk.AutoSize = true; // 自动调整大小
            chk.Location = location;
            chk.Anchor = AnchorStyles.Left | AnchorStyles.Top;
            chk.CheckedChanged += Chk_CheckedChanged; // 勾选状态改变   
            return chk;
        }

        /// <summary>
        /// 管理动态序列--添加、移除序列
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Chk_CheckedChanged(object sender, EventArgs e)
        {
            CheckBox chk = sender as CheckBox;
            if (chk.Tag != null)
            {
                // 参数名
                string pName = chk.Tag.ToString();
                if (chk.Checked)
                {
                    AddSeries(pName); // 添加序列
                }
                else
                {
                    RemoveSeries(pName); // 移除序列
                }
            }
        }

        /// <summary>
        /// 添加序列
        /// </summary>
        /// <param name="paraName"></param>
        private void AddSeries(string paraName)
        {
            // 参数描述 
            string paraNote = CommonClass.trendParaInfos.FirstOrDefault(a => a.ParaName == paraName).Note;
            // 创建序列
            Series series = new Series(paraNote);
            // 曲线图
            series.ChartType = SeriesChartType.Spline;
            series.Tag = paraName;
            // 曲线的粗细
            series.BorderWidth = 3;
            // X轴的值类型
            series.XValueType = ChartValueType.DateTime;
            chart1.Series.Add(series);
        }

        /// <summary>
        /// 移除序列
        /// </summary>
        private void RemoveSeries(string paraName)
        {
            // 参数描述
            string paraNote = CommonClass.trendParaInfos.FirstOrDefault(a => a.ParaName == paraName).Note;
            if (chart1.Series.Count > 0)
            {
                // 查找序列
                Series series = chart1.Series.FindByName(paraNote);
                if (series != null)
                    chart1.Series.Remove(series);
            }
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            if (btnStart.Text == "开始")
            {
                timer.Start();
                btnStart.Text = "停止";
            }
            else
            {
                timer.Stop();
                btnStart.Text = "开始";
            }
        }
    }
}
